/**
    \file env.h
    \brief Defines the environment of the source file.
*/

/** @defgroup environment  Environment
 * The Module of the environment<br>
 * We uses 2 different environment, one stores functions and another stores
 * variables and types. By doing this we can declare variable and function
 * with the same name.
 * @{
*/
#ifndef __ENV_H__
#define __ENV_H__

#include "util.h"
#include "table.h"
#include "types.h"
#include "temp.h" 
#include "translate.h"

typedef struct E_enventry_ *E_enventry;

///Entry structure stored in the enviroment
struct E_enventry_
{
    ///The type of the enventrey
    enum { E_varEntry, E_funEntry } kind;
    ///Union that stores the info of the entry
    union
    {
        struct
        {
            Tr_access access;
            Ty_ty ty;
        } var;    ///Variable entry

        struct
        {
            Tr_level level;
            Temp_label label;
                Ty_tyList formals;
                Ty_ty result;
                bool imped;
        } fun;    ///<Function entry
    } u;
};

/// Create EnvEntry
E_enventry E_VarEntry(Tr_access access, Ty_ty ty);
E_enventry E_FunEntry(Tr_level level, Temp_label label, Ty_tyList formals, Ty_ty result);

// Create a envrionment
S_table E_base_tenv();    ///Create a type environment
S_table E_base_venv();    ///Create a var environment using E_enventry

void E_tenter(S_table t, S_symbol sym, Ty_ty type);
void E_venter(S_table t, S_symbol sym, E_enventry entry);

#endif

///@}

